﻿using System;
using System.Runtime.InteropServices;

namespace LDSModel.Item
{

    /// <summary>
    /// 时间结构。
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public class StuTime
    {
        [FieldOffset(0)]
        byte _Second;
        [FieldOffset(1)]
        byte _Minute;
        [FieldOffset(2)]
        byte _Hour;
        [FieldOffset(3)]
        byte _DayOfWeek;

        public int Second
        {
            set { _Second = Convert.ToByte((_Second & 0xC0) | (value & 0x3F)); }
            get { return (_Second & 0x3F); }
        }

        public int Minute
        {
            set { _Minute = Convert.ToByte((_Minute & 0xC0) | (value & 0x3F)); }
            get { return (_Minute & 0x3F); }
        }

        public int Hour
        {
            set { _Hour = Convert.ToByte((_Hour & 0xE0) | (value & 0x1F)); }
            get { return (_Hour & 0x1F); }
        }

        public int DayOfWeek
        {
            set { _DayOfWeek = Convert.ToByte((_DayOfWeek & 0xF8) | (value & 0x07)); }
            get { return (_DayOfWeek & 0x07); }
        }

        public StuTime()
        {

        }

        public StuTime(DateTime dateTime)
        {
            Second = dateTime.Second;
            Minute = dateTime.Minute;
            Hour = dateTime.Hour;
            DayOfWeek = (int)dateTime.DayOfWeek;
        }

    }

    /// <summary>
    /// 日期结构。
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public class StuDate
    {
        [FieldOffset(0)]
        byte _DayOfMonth;
        [FieldOffset(1)]
        byte _Month;
        [FieldOffset(2)]
        UInt16 _Year;

        public int DayOfMonth
        {
            set { _DayOfMonth = Convert.ToByte((_DayOfMonth & 0xE0) | (value & 0x1F)); }
            get { return (_DayOfMonth & 0x1F); }
        }

        public int Month
        {
            set { _Month = Convert.ToByte((_Month & 0xF0) | (value & 0x0F)); }
            get { return (_Month & 0x0F); }
        }

        public int Year
        {
            set { _Year = Convert.ToUInt16((_Year & 0xF000) | (value & 0x0FFF)); }
            get { return (_Year & 0x0FFF); }
        }

        public StuDate() { }
        public StuDate(DateTime dateTime)
        {
            DayOfMonth = dateTime.Day;
            Month = dateTime.Month;
            Year = dateTime.Year;
        }
    }

    /// <summary>
    /// RTC日期时间结构。
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public class RtcDateTime
    {
        [FieldOffset(0)]
        public StuTime Time;

        [FieldOffset(4)]
        public StuDate Date;

        [FieldOffset(8)]
        private int _DayOfYear;

        public int DayOfYear
        {
            set { _DayOfYear = Convert.ToInt32((_DayOfYear & 0xF000) | (value & 0x0FFF)); }
            get { return (_DayOfYear & 0x0FFF); }
        }

        public RtcDateTime()
        {
            Time = new StuTime();
            Date = new StuDate();
        }

        public RtcDateTime(DateTime dateTime)
        {
            Time = new StuTime(dateTime);
            Date = new StuDate(dateTime);
            DayOfYear = dateTime.DayOfYear;
        }

        public DateTime ToSystemTime()
        {
            DateTime dt;
            try
            {
                dt = new DateTime(Date.Year, Date.Month, Date.DayOfMonth, Time.Hour, Time.Minute, Time.Second);
            }
            catch
            {
                dt = new DateTime(2000, 1, 1, 0, 0, 0);
            }
            return dt;
            //dt.Year = this.Date.Year;
            //dt.Month = this.Date.Month;
            //dt.Day = this.Date.DayOfMonth;

            //dt.Hour = this.Time.Hour;
            //dt.Minute = this.Time.Minute;
            //dt.Second = this.Time.Second;
            //dt.DayOfWeek = this.Time.DayOfWeek;
            //dt.DayOfYear = this.DayOfYear;
        }

    }
}
